<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <meta name="description" content="JinYan&#39;s blog">
  <meta name="keyword" content="hexo-theme, vuejs">
  
    <link rel="shortcut icon" href="/blog/css/images/logo.jpg">
  
  <title>
    
      Python-3-面向对象 | SanYuanEmpire
    
  </title>
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link href="//cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
  <link href="//cdn.bootcss.com/highlight.js/9.12.0/styles/tomorrow.min.css" rel="stylesheet">
  <link rel="stylesheet" href="/blog/css/style.css">
<link rel="stylesheet" href="/blog/css/plugins/gitment.css">
  <script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  <script src="//cdn.bootcss.com/geopattern/1.2.3/js/geopattern.min.js"></script>
  <script src="//cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js"></script>
  <script src="/blog/js/qrious.js"></script>
<script src="/blog/js/gitment.js"></script>
  
  
    <!-- MathJax support START -->
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <!-- MathJax support END -->
  


</head>
<div class="wechat-share">
  <img src="/css/images/logo.jpg" />
</div>

  <body>
    <header class="header fixed-header">
  <div class="header-container">
    <a class="home-link" href="/blog/">
      <div class="logo"></div>
      <span>SanYuanEmpire</span>
    </a>
    <ul class="right-list">
      
        <li class="list-item">
          
            <a href="/blog/" class="item-link">Home</a>
          
        </li>
      
        <li class="list-item">
          
            <a href="/blog/archives/" class="item-link">Archives</a>
          
        </li>
      
    </ul>
    <div class="menu">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </div>
    <div class="menu-mask">
      <ul class="menu-list">
        
          <li class="menu-item">
            
              <a href="/blog/" class="menu-link">Home</a>
            
          </li>
        
          <li class="menu-item">
            
              <a href="/blog/archives/" class="menu-link">Archives</a>
            
          </li>
        
      </ul>
    </div>
  </div>
</header>

    <div id="article-banner">
  <h2>Python-3-面向对象</h2>
  <p class="post-date">2018-09-03</p>
  <div class="arrow-down">
    <a href="javascript:;"></a>
  </div>
</div>
<main class="app-body flex-box">
  <!-- Article START -->
  <article class="post-article">
    <section class="markdown-content"><h1 id="面向对象"><a href="#面向对象" class="headerlink" title="面向对象"></a>面向对象</h1><ul>
<li>类与对象是面向对象编程的两个主要方面。一个类（Class）能够创建一种新的类型（Type），其中对象（Object）就是类的实例（Instance）。可以这样来类比：你可以拥有类型 int 的变量，也就是说存储整数的变量是 int 类的实例（对象）。<blockquote>
<p>类(Class)：用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。<br>方法：类中定义的函数。<br>类变量：类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。<br>数据成员：类变量或者实例变量用于处理类及其实例对象的相关的数据。<br>方法重写：如果从父类继承的方法不能满足子类的需求，可以对其进行改写，这个过程叫方法的覆盖（override），也称为方法的重写。<br>实例变量：定义在方法中的变量，只作用于当前实例的类。<br>继承：即一个派生类（derived class）继承基类（base class）的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如，有这样一个设计：一个Dog类型的对象派生自Animal类，这是模拟”是一个（is-a）”关系（例图，Dog是一个Animal）。<br>实例化：创建一个类的实例，类的具体对象。<br>对象：通过类定义的数据结构实例。对象包括两个数据成员（类变量和实例变量）和方法。</p>
</blockquote>
</li>
</ul>
<blockquote>
<p>Python 中的类提供了面向对象编程的所有基本功能：类的继承机制允许多个基类，派生类可以覆盖基类中的任何方法，方法中可以调用基类中的同名方法。<br>对象可以包含任意数量和类型的数据。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">self</span><br><span class="line">self 表示的是当前实例，代表当前对象的地址。类由 self.__class__ 表示。</span><br><span class="line">self 不是关键字，其他名称也可以替代，但 self 是个通用的标准名称。</span><br></pre></td></tr></table></figure></p>
</blockquote>
<h1 id="类"><a href="#类" class="headerlink" title="类"></a>类</h1><ul>
<li>类由 class 关键字来创建。 类实例化后，可以使用其属性，实际上，创建一个类之后，可以通过类名访问其属性。</li>
</ul>
<h1 id="对象方法"><a href="#对象方法" class="headerlink" title="对象方法"></a>对象方法</h1><ul>
<li>方法由 def 关键字定义，与函数不同的是，方法必须包含参数 self, 且为第一个参数，self 代表的是本类的实例。</li>
</ul>
<h1 id="类方法"><a href="#类方法" class="headerlink" title="类方法"></a>类方法</h1><ul>
<li>装饰器 @classmethod 可以将方法标识为类方法。类方法的第一个参数必须为 cls，而不再是 self。</li>
</ul>
<h1 id="静态方法"><a href="#静态方法" class="headerlink" title="静态方法"></a>静态方法</h1><ul>
<li>装饰器 @staticmethod 可以将方法标识为静态方法。静态方法的第一个参数不再指定，也就不需要 self 或 cls。</li>
</ul>
<h1 id="init-方法"><a href="#init-方法" class="headerlink" title="init 方法"></a><strong>init</strong> 方法</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">__init__ 方法即构造方法，会在类的对象被实例化时先运行，可以将初始化的操作放置到该方法中。</span><br><span class="line">如果重写了 __init__，实例化子类就不会调用父类已经定义的 __init__。</span><br></pre></td></tr></table></figure>
<h1 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h1><blockquote>
<p>类变量（Class Variable）是共享的（Shared）——它们可以被属于该类的所有实例访问。该类变量只拥有一个副本，当任何一个对象对类变量作出改变时，发生的变动将在其它所有实例中都会得到体现。<br>对象变量（Object variable）由类的每一个独立的对象或实例所拥有。在这种情况下，每个对象都拥有属于它自己的字段的副本，也就是说，它们不会被共享，也不会以任何方式与其它不同实例中的相同名称的字段产生关联。<br>在 Python 中，变量名类似 <strong>xxx</strong> 的，也就是以双下划线开头，并且以双下划线结尾的，是特殊变量，特殊变量是可以直接访问的，不是 private 变量，所以，不能用 <strong>name</strong>、<strong>score</strong> 这样的变量名。</p>
</blockquote>
<h1 id="访问控制"><a href="#访问控制" class="headerlink" title="访问控制"></a>访问控制</h1><h2 id="私有属性"><a href="#私有属性" class="headerlink" title="私有属性"></a>私有属性</h2><ul>
<li>__private_attr：两个下划线开头，声明该属性为私有，不能在类地外部被使用或直接访问。<h2 id="私有方法"><a href="#私有方法" class="headerlink" title="私有方法"></a>私有方法</h2></li>
<li>__private_method：两个下划线开头，声明该方法为私有方法，只能在类的内部调用，不能在类地外部调用。</li>
<li>我们还认为约定，一个下划线开头的属性或方法为受保护的。比如，_protected_attr、_protected_method。</li>
</ul>
<h1 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h1><blockquote>
<p>类可以继承，并且支持继承多个父类。在定义类时，类名后的括号中指定要继承的父类，多个父类之间用逗号分隔。<br>子类的实例可以完全访问所继承所有父类的非私有属性和方法。<br>若是父类中有相同的方法名，而在子类使用时未指定，Python 从左至右搜索，即方法在子类中未找到时，从左到右查找父类中是否包含方法。</p>
</blockquote>
<h1 id="方法重写"><a href="#方法重写" class="headerlink" title="方法重写"></a>方法重写</h1><blockquote>
<p>子类的方法可以重写父类的方法。重写的方法参数不强制要求保持一致，不过合理的设计都应该保持一致。<br>super() 函数可以调用父类的一个方法，以多继承问题。</p>
</blockquote>
<blockquote>
<p>类的专有方法<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">__init__: 构造函数，在生成对象时调用</span><br><span class="line">__del__: 析构函数，释放对象时使用</span><br><span class="line">__repr__: 打印，转换</span><br><span class="line">__setitem__: 按照索引赋值</span><br><span class="line">__getitem__: 按照索引获取值</span><br><span class="line">__len__: 获得长度</span><br><span class="line">__cmp__: 比较运算</span><br><span class="line">__call__: 函数调用</span><br><span class="line">__add__: 加运算</span><br><span class="line">__sub__: 减运算</span><br><span class="line">__mul__: 乘运算</span><br><span class="line">__div__: 除运算</span><br><span class="line">__mod__: 求余运算</span><br><span class="line">__pow__: 乘方</span><br><span class="line">类的专有方法也支持重载。</span><br></pre></td></tr></table></figure></p>
</blockquote>
<h1 id="实例"><a href="#实例" class="headerlink" title="实例"></a>实例</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br></pre></td><td class="code"><pre><span class="line">class Person:</span><br><span class="line">    &quot;&quot;&quot;人员信息&quot;&quot;&quot;</span><br><span class="line">    # 姓名(共有属性)</span><br><span class="line">    name = &apos;&apos;</span><br><span class="line">    # 年龄(共有属性)</span><br><span class="line">    age = 0</span><br><span class="line">    def __init__(self, name=&apos;&apos;, age=0):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line">    # 重载专有方法: __str__</span><br><span class="line">    def __str__(self):</span><br><span class="line">        return &quot;这里重载了 __str__ 专有方法, &quot; + str(&#123;&apos;name&apos;: self.name, &apos;age&apos;: self.age&#125;)</span><br><span class="line">    def set_age(self, age):</span><br><span class="line">        self.age = age</span><br><span class="line">class Account:</span><br><span class="line">    &quot;&quot;&quot;账户信息&quot;&quot;&quot;</span><br><span class="line">    # 账户余额(私有属性)</span><br><span class="line">    __balance = 0</span><br><span class="line">    # 所有账户总额</span><br><span class="line">    __total_balance = 0</span><br><span class="line">    # 获取账户余额</span><br><span class="line">    # self 必须是方法的第一个参数</span><br><span class="line">    def balance(self):</span><br><span class="line">        return self.__balance</span><br><span class="line">    # 增加账户余额</span><br><span class="line">    def balance_add(self, cost):</span><br><span class="line">        # self 访问的是本实例</span><br><span class="line">        self.__balance += cost</span><br><span class="line">        # self.__class__ 可以访问类</span><br><span class="line">        self.__class__.__total_balance += cost</span><br><span class="line">    # 类方法(用 @classmethod 标识，第一个参数为 cls)</span><br><span class="line">    @classmethod</span><br><span class="line">    def total_balance(cls):</span><br><span class="line">        return cls.__total_balance</span><br><span class="line">    # 静态方法(用 @staticmethod 标识，不需要类参数或实例参数)</span><br><span class="line">    @staticmethod</span><br><span class="line">    def exchange(a, b):</span><br><span class="line">        return b, a</span><br><span class="line">class Teacher(Person, Account):</span><br><span class="line">    &quot;&quot;&quot;教师&quot;&quot;&quot;</span><br><span class="line">    # 班级名称</span><br><span class="line">    _class_name = &apos;&apos;</span><br><span class="line">    def __init__(self, name):</span><br><span class="line">        # 第一种重载父类__init__()构造方法</span><br><span class="line">        # super(子类，self).__init__(参数1，参数2，....)</span><br><span class="line">        super(Teacher, self).__init__(name)</span><br><span class="line">    def get_info(self):</span><br><span class="line">        # 以字典的形式返回个人信息</span><br><span class="line">        return &#123;</span><br><span class="line">            &apos;name&apos;: self.name, # 此处访问的是父类Person的属性值</span><br><span class="line">            &apos;age&apos;: self.age,</span><br><span class="line">            &apos;class_name&apos;: self._class_name,</span><br><span class="line">            &apos;balance&apos;: self.balance(), # 此处调用的是子类重载过的方法</span><br><span class="line">        &#125;</span><br><span class="line">    # 方法重载</span><br><span class="line">    def balance(self):</span><br><span class="line">        # Account.__balance 为私有属性，子类无法访问，所以父类提供方法进行访问</span><br><span class="line">        return Account.balance(self) * 1.1</span><br><span class="line">class Student(Person, Account):</span><br><span class="line">    &quot;&quot;&quot;学生&quot;&quot;&quot;</span><br><span class="line">    _teacher_name = &apos;&apos;</span><br><span class="line">    def __init__(self, name, age=18):</span><br><span class="line">        # 第二种重载父类__init__()构造方法</span><br><span class="line">        # 父类名称.__init__(self,参数1，参数2，...)</span><br><span class="line">        Person.__init__(self, name, age)</span><br><span class="line">    def get_info(self):</span><br><span class="line">        # 以字典的形式返回个人信息</span><br><span class="line">        return &#123;</span><br><span class="line">            &apos;name&apos;: self.name, # 此处访问的是父类Person的属性值</span><br><span class="line">            &apos;age&apos;: self.age,</span><br><span class="line">            &apos;teacher_name&apos;: self._teacher_name,</span><br><span class="line">            &apos;balance&apos;: self.balance(),</span><br><span class="line">        &#125;</span><br><span class="line"># 教师 John</span><br><span class="line">john = Teacher(&apos;John&apos;)</span><br><span class="line">john.balance_add(20)</span><br><span class="line">john.set_age(36) # 子类的实例可以直接调用父类的方法</span><br><span class="line">print(&quot;John&apos;s info:&quot;, john.get_info())</span><br><span class="line"># 学生 Mary</span><br><span class="line">mary = Student(&apos;Mary&apos;, 18)</span><br><span class="line">mary.balance_add(18)</span><br><span class="line">print(&quot;Mary&apos;s info:&quot;, mary.get_info())</span><br><span class="line"># 学生 Fake</span><br><span class="line">fake = Student(&apos;Fake&apos;)</span><br><span class="line">fake.balance_add(30)</span><br><span class="line">print(&quot;Fake&apos;s info&quot;, fake.get_info())</span><br><span class="line"># 三种不同的方式调用静态方法</span><br><span class="line">print(&quot;john.exchange(&apos;a&apos;, &apos;b&apos;):&quot;, john.exchange(&apos;a&apos;, &apos;b&apos;))</span><br><span class="line">print(&apos;Teacher.exchange(1, 2)&apos;, Teacher.exchange(1, 2))</span><br><span class="line">print(&apos;Account.exchange(10, 20):&apos;, Account.exchange(10, 20))</span><br><span class="line"># 类方法、类属性</span><br><span class="line">print(&apos;Account.total_balance():&apos;, Account.total_balance())</span><br><span class="line">print(&apos;Teacher.total_balance():&apos;, Teacher.total_balance())</span><br><span class="line">print(&apos;Student.total_balance():&apos;, Student.total_balance())</span><br><span class="line"># 重载专有方法</span><br><span class="line">print(fake)</span><br><span class="line">输出：</span><br><span class="line">John&apos;s info: &#123;&apos;name&apos;: &apos;John&apos;, &apos;age&apos;: 36, &apos;class_name&apos;: &apos;&apos;, &apos;balance&apos;: 22.0&#125;</span><br><span class="line">Mary&apos;s info: &#123;&apos;name&apos;: &apos;Mary&apos;, &apos;age&apos;: 18, &apos;teacher_name&apos;: &apos;&apos;, &apos;balance&apos;: 18&#125;</span><br><span class="line">Fake&apos;s info &#123;&apos;name&apos;: &apos;Fake&apos;, &apos;age&apos;: 18, &apos;teacher_name&apos;: &apos;&apos;, &apos;balance&apos;: 30&#125;</span><br><span class="line">john.exchange(&apos;a&apos;, &apos;b&apos;): (&apos;b&apos;, &apos;a&apos;)</span><br><span class="line">Teacher.exchange(1, 2) (2, 1)</span><br><span class="line">Account.exchange(10, 20): (20, 10)</span><br><span class="line">Account.total_balance(): 0</span><br><span class="line">Teacher.total_balance(): 20</span><br><span class="line">Student.total_balance(): 48</span><br><span class="line">这里重载了 __str__ 专有方法, &#123;&apos;name&apos;: &apos;Fake&apos;, &apos;age&apos;: 18&#125;</span><br></pre></td></tr></table></figure>
</section>
    <!-- Tags START -->
    
    <!-- Tags END -->
    <!-- NAV START -->
    
  <div class="nav-container">
    <!-- reverse left and right to put prev and next in a more logic postition -->
    
      <a class="nav-left" href="/blog/2018/09/03/Python-3-错误和异常/">
        <span class="nav-arrow">← </span>
        
          Python-3-错误和异常
        
      </a>
    
    
      <a class="nav-right" href="/blog/2018/09/03/Python-3-文件操作/">
        
          Python-3-文件操作
        
        <span class="nav-arrow"> →</span>
      </a>
    
  </div>

    <!-- NAV END -->
    
      <!-- No Comment -->
    
  </article>
  <!-- Article END -->
  <!-- Catalog START -->
  
    <aside class="catalog-container">
  <div class="toc-main">
    <strong class="toc-title">Catalog</strong>
    
      <ol class="toc-nav"><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#面向对象"><span class="toc-nav-text">面向对象</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#类"><span class="toc-nav-text">类</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#对象方法"><span class="toc-nav-text">对象方法</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#类方法"><span class="toc-nav-text">类方法</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#静态方法"><span class="toc-nav-text">静态方法</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#init-方法"><span class="toc-nav-text">init 方法</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#变量"><span class="toc-nav-text">变量</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#访问控制"><span class="toc-nav-text">访问控制</span></a><ol class="toc-nav-child"><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#私有属性"><span class="toc-nav-text">私有属性</span></a></li><li class="toc-nav-item toc-nav-level-2"><a class="toc-nav-link" href="#私有方法"><span class="toc-nav-text">私有方法</span></a></li></ol></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#继承"><span class="toc-nav-text">继承</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#方法重写"><span class="toc-nav-text">方法重写</span></a></li><li class="toc-nav-item toc-nav-level-1"><a class="toc-nav-link" href="#实例"><span class="toc-nav-text">实例</span></a></li></ol>
    
  </div>
</aside>
  
  <!-- Catalog END -->
</main>

<script>
  (function () {
    var url = 'git@gitee.com:sanyuanempire/blog.git/2018/09/03/Python-3-面向对象/';
    var banner = ''
    if (banner !== '' && banner !== 'undefined' && banner !== 'null') {
      $('#article-banner').css({
        'background-image': 'url(' + banner + ')'
      })
    } else {
      $('#article-banner').geopattern(url)
    }
    $('.header').removeClass('fixed-header')

     // error image
    $(".markdown-content img").on('error', function() {
      $(this).attr('src', 'http://file.muyutech.com/error-img.png')
      $(this).css({
        'cursor': 'default'
      })
    })

    // zoom image
    $(".markdown-content img").on('click', function() {
      var src = $(this).attr('src')
      if (src !== 'http://file.muyutech.com/error-img.png') {
        var imageW = $(this).width()
        var imageH = $(this).height()
        
        var zoom = ($(window).width() * 0.95 / imageW).toFixed(2)
        zoom = zoom < 1 ? 1 : zoom
        zoom = zoom > 2 ? 2 : zoom
        var transY = (($(window).height() - imageH) / 2).toFixed(2)

        $('body').append('<div class="image-view-wrap"><div class="image-view-inner"><img src="'+ src +'" /></div></div>')
        $('.image-view-wrap').addClass('wrap-active')
        $('.image-view-wrap img').css({
          'width': `${imageW}`,
          'transform': `translate3d(0, ${transY}px, 0) scale3d(${zoom}, ${zoom}, 1)`
        })
        $('html').css('overflow', 'hidden')

        $('.image-view-wrap').on('click', function() {
          $(this).remove()
          $('html').attr('style', '')
        })
      }
    })

    // qrcode
    var qr = new QRious({
      element: document.getElementById('share-qrcode'),
      value: document.location.href
    });

    // gitment
    var gitmentConfig = "";
    if (gitmentConfig !== 'undefined') {
      var gitment = new Gitment({
        id: "Python-3-面向对象",
        owner: "",
        repo: "",
        oauth: {
          client_id: "",
          client_secret: ""
        },
        theme: {
          render(state, instance) {
            const container = document.createElement('div')
            container.lang = "en-US"
            container.className = 'gitment-container gitment-root-container'
            container.appendChild(instance.renderHeader(state, instance))
            container.appendChild(instance.renderEditor(state, instance))
            container.appendChild(instance.renderComments(state, instance))
            container.appendChild(instance.renderFooter(state, instance))
            return container;
          }
        }
      })
      gitment.render(document.getElementById('comments'))
    }
  })();
</script>

<script>
  var disqus_shortname = '';
  
  var disqus_url = 'git@gitee.com:sanyuanempire/blog.git/2018/09/03/Python-3-面向对象/';
  
  (function(){
    var dsq = document.createElement('script');
    dsq.type = 'text/javascript';
    dsq.async = true;
    dsq.src = '//go.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>

    <div class="scroll-top">
  <span class="arrow-icon"></span>
</div>
    <footer class="app-footer">
  <p class="copyright">
    &copy; 2018 | Proudly powered by <a href="https://sanyuanempire.gitee.io/blog" target="_blank">JinYan</a>
    <br>
    Theme by <a href="https://sanyuanempire.gitee.io/blog">JinYan</a>
  </p>
</footer>

<script>
  function async(u, c) {
    var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.insertBefore(o, s);
  }
</script>
<script>
  async("//cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function(){
    FastClick.attach(document.body);
  })
</script>

<script>
  var hasLine = 'true';
  async("//cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js", function(){
    $('figure pre').each(function(i, block) {
      var figure = $(this).parents('figure');
      if (hasLine === 'false') {
        figure.find('.gutter').hide();
      }
      var lang = figure.attr('class').split(' ')[1] || 'code';
      var codeHtml = $(this).html();
      var codeTag = document.createElement('code');
      codeTag.className = lang;
      codeTag.innerHTML = codeHtml;
      $(this).attr('class', '').empty().html(codeTag);
      figure.attr('data-lang', lang.toUpperCase());
      hljs.highlightBlock(block);
    });
  })
</script>
<!-- Baidu Tongji -->

<script src="/blog/js/script.js"></script>

  </body>
</html>